home *** CD-ROM | disk | FTP | other *** search
/ Aminet 5 / Aminet 5 - March 1995.iso / Aminet / util / cli / bangtools.lha / src / callfunc.c next >
C/C++ Source or Header  |  1995-01-15  |  6KB  |  186 lines

  1. /* callfunc - call shared library function in a shell script
  2.  *
  3.  * Copyright (C) 1995 by Ingo Wilken (Ingo.Wilken@informatik.uni-oldenburg.de)
  4.  *
  5.  * Permission to use, copy, modify, and distribute this software and its
  6.  * documentation for any purpose and without fee is hereby granted, provided
  7.  * that the above copyright notice appear in all copies and that both that
  8.  * copyright notice and this permission notice appear in supporting
  9.  * documentation.  This software is provided "as is" without express or
  10.  * implied warranty.
  11.  *
  12.  * V1.0: 12/Jan/95 first version
  13.  */
  14. #define THIS_PROGRAM    "callfunc"
  15. #define THIS_VERSION    "1.0"
  16.  
  17. static const char amiga_version[] = "\0$VER: " THIS_PROGRAM " " THIS_VERSION " (" __COMMODORE_DATE__ ")";
  18.  
  19. #include <exec/types.h>
  20. #include <exec/libraries.h>
  21. #include <dos/dos.h>
  22. #include <dos/rdargs.h>
  23. #include <stdlib.h>
  24. #include <string.h>
  25.  
  26. #define SysBase_DECLARED
  27. #include <proto/exec.h>
  28. #include <proto/dos.h>
  29. #include <proto/utility.h>
  30.  
  31. extern struct Library *SysBase;
  32.  
  33. extern __stkargs LONG CallFunction(struct Library *base, LONG offset,
  34.                                     LONG d0, LONG d1, LONG d2, LONG d3, LONG d4,
  35.                                     LONG d5, LONG d6, LONG d7,
  36.                                     APTR a0, APTR a1, APTR a2, APTR a3, APTR a4);
  37.  
  38.  
  39. const char Template[] =
  40.     "OFFSET/N,FROM/K,D0/K,D1/K,D2/K,D3/K,D4/K,D5/K,D6/K,D7/K,A0/K,A1/K,A2/K,A3/K,A4/K,VOID/S,OPEN/K,CLOSE/K,VER=VERSION/K/N";
  41.  
  42. __aligned struct {
  43.     LONG *  offset;
  44.     STRPTR  libbase;
  45.     STRPTR  D0, D1, D2, D3, D4, D5, D6, D7;
  46.     STRPTR  A0, A1, A2, A3, A4;
  47.     LONG    noresult;   /* 'void' */
  48.     STRPTR  open;
  49.     STRPTR  close;
  50.     LONG *  libversion;
  51. } Args;
  52.  
  53.  
  54.  
  55. static APTR mkaddr(STRPTR str);
  56.  
  57. void
  58. _main()
  59. {
  60.     struct RDArgs *rdargs;
  61.     LONG rc = RETURN_OK;
  62.  
  63.     struct Library *cfbase;
  64.     char *dummy;
  65.     LONG result;
  66.  
  67.     char buf[16] = {0};
  68.     /* RawDoFmt() 'put' function
  69.      * MC68000 machine code:
  70.      *      move.b d0,(a3)+
  71.      *      rts
  72.      * Idea by Doug Walker, walker@unx.sas.com
  73.      */
  74.     __aligned const unsigned char rawdocode[] = { 0x16, 0xC0, 0x4E, 0x75 };
  75.  
  76.  
  77.     if( SysBase->lib_Version < 37 ) {
  78.         #define MESSAGE "requires AmigaOS 2.04 or higher\n"
  79.         Write(Output(), MESSAGE, sizeof(MESSAGE)-1);
  80.         _exit(RETURN_FAIL);
  81.         #undef MESSAGE
  82.     }
  83.  
  84.     if( rdargs = ReadArgs(Template, (LONG *)&Args, NULL) ) {
  85.         LONG libversion = 0;
  86.         if( Args.libversion )
  87.             libversion = *(Args.libversion);
  88.  
  89.         if( Args.open ) {
  90.             cfbase = OpenLibrary(Args.open, libversion);
  91.             RawDoFmt("%ld\n", (APTR)&cfbase, (void (*)())rawdocode, buf);
  92.             PutStr(buf);
  93.             if( !cfbase )
  94.                 rc = RETURN_WARN;
  95.         }
  96.         else
  97.         if( Args.close ) {
  98.             cfbase = (struct Library *)strtoul(Args.close, &dummy, 0);
  99.             if( cfbase )
  100.                 CloseLibrary(cfbase);
  101.             else {
  102.                 PutStr("invalid library base\n");
  103.                 rc = RETURN_WARN;
  104.             }
  105.         }
  106.         else {
  107.             BOOL closelib = FALSE;
  108.  
  109.             cfbase = (struct Library *)strtoul(Args.libbase, &dummy, 0);
  110.             if( !cfbase || *dummy ) {
  111.                 cfbase = OpenLibrary(Args.libbase, libversion);
  112.                 closelib = TRUE;
  113.             }
  114.  
  115.             if( !cfbase ) {
  116.                 PutStr("invalid library name or base\n");
  117.                 rc = RETURN_ERROR;
  118.                 cfbase = NULL;
  119.             }
  120.             else {
  121.                 LONG d0 = 0, d1 = 0, d2 = 0, d3 = 0, d4 = 0, d5 = 0, d6 = 0, d7 = 0;
  122.                 APTR a0 = 0, a1 = 0, a2 = 0, a3 = 0, a4 = 0;
  123.                 LONG offset = 0;
  124.  
  125.                 if( Args.offset )
  126.                     offset = *(Args.offset);
  127.                 if( offset > 0 )
  128.                     offset = -offset;
  129.                 if( (offset % 6) || (offset > -30) ) {
  130.                     PutStr("invalid library offset\n");
  131.                     rc = RETURN_ERROR;
  132.                 }
  133.                 else {
  134.                     d0 = (LONG)mkaddr(Args.D0);
  135.                     d1 = (LONG)mkaddr(Args.D1);
  136.                     d2 = (LONG)mkaddr(Args.D2);
  137.                     d3 = (LONG)mkaddr(Args.D3);
  138.                     d4 = (LONG)mkaddr(Args.D4);
  139.                     d5 = (LONG)mkaddr(Args.D5);
  140.                     d6 = (LONG)mkaddr(Args.D6);
  141.                     d7 = (LONG)mkaddr(Args.D7);
  142.                     a0 = mkaddr(Args.A0);
  143.                     a1 = mkaddr(Args.A1);
  144.                     a2 = mkaddr(Args.A2);
  145.                     a3 = mkaddr(Args.A3);
  146.                     a4 = mkaddr(Args.A4);
  147.  
  148.                     result = CallFunction(cfbase, offset, d0, d1, d2, d3, d4, d5, d6, d7,
  149.                                             a0, a1, a2, a3, a4);
  150.                     if( !Args.noresult ) {
  151.                         RawDoFmt("%ld\n", (APTR)&result, (void (*)())rawdocode, buf);
  152.                         PutStr(buf);
  153.                     }
  154.                 }
  155.                 if( closelib )
  156.                     CloseLibrary(cfbase);
  157.             }
  158.         }
  159.         FreeArgs(rdargs);
  160.     }
  161.     else {
  162.         PutStr("required argument missing\n");
  163.         rc = RETURN_ERROR;
  164.     }
  165.     _exit((int)rc);
  166. }
  167.  
  168.  
  169.  
  170. static APTR
  171. mkaddr(STRPTR str)
  172. {
  173.     APTR adr = NULL;
  174.  
  175.     if( str ) {
  176.         if( str[0] == '@' )
  177.             adr = (APTR)(str+1);
  178.         else {
  179.             char *dummy;
  180.             adr = (APTR)strtoul(str, &dummy, 0);
  181.         }
  182.     }
  183.     return adr;
  184. }
  185.  
  186.